package com.sqlcheck.service.impl;

import com.sqlcheck.model.SqlStatement;
import com.sqlcheck.service.CodeAnalysisService;
import com.sqlcheck.service.JavaAnnotationAnalysisService;
import com.sqlcheck.service.MybatisXmlAnalysisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

@Slf4j
@Service
@RequiredArgsConstructor
public class CodeAnalysisServiceImpl implements CodeAnalysisService {

    private final MybatisXmlAnalysisService mybatisXmlAnalysisService;
    private final JavaAnnotationAnalysisService javaAnnotationAnalysisService;

    @Override
    public List<SqlStatement> analyzeProject(Path projectPath) {
        List<SqlStatement> allSqlStatements = new ArrayList<>();

        try {
            if (!Files.exists(projectPath) || !Files.isDirectory(projectPath)) {
                log.warn("项目路径不存在或不是目录: {}", projectPath);
                return allSqlStatements;
            }

            log.info("开始分析项目: {}", projectPath);

            // 分析所有子目录
            allSqlStatements.addAll(analyzeDirectory(projectPath, true));

            log.info("项目分析完成，共提取到 {} 条SQL语句", allSqlStatements.size());

        } catch (Exception e) {
            log.error("分析项目失败: " + projectPath, e);
        }

        return allSqlStatements;
    }

    @Override
    public List<SqlStatement> analyzeDirectory(Path directoryPath, boolean includeSubDirs) {
        List<SqlStatement> allSqlStatements = new ArrayList<>();

        try {
            if (!Files.exists(directoryPath) || !Files.isDirectory(directoryPath)) {
                log.warn("目录不存在或不是目录: {}", directoryPath);
                return allSqlStatements;
            }

            log.info("开始分析目录: {} (包含子目录: {})", directoryPath, includeSubDirs);

            final int[] fileCounts = { 0, 0, 0, 0, 0 }; // total, xml, java, sql, other

            try (Stream<Path> paths = includeSubDirs ? Files.walk(directoryPath) : Files.list(directoryPath)) {
                paths.filter(Files::isRegularFile)
                        .forEach(filePath -> {
                            fileCounts[0]++; // total
                            String fileName = filePath.toString().toLowerCase();

                            if (fileName.endsWith(".xml")) {
                                fileCounts[1]++; // xml
                            } else if (fileName.endsWith(".java")) {
                                fileCounts[2]++; // java
                            } else if (fileName.endsWith(".sql")) {
                                fileCounts[3]++; // sql
                            } else {
                                fileCounts[4]++; // other
                            }

                            List<SqlStatement> statements = analyzeFile(filePath);
                            allSqlStatements.addAll(statements);
                        });
            }

            log.info("目录分析完成: {} -> 总文件={}, XML={}, Java={}, SQL={}, 其他={}, SQL语句={}",
                    directoryPath, fileCounts[0], fileCounts[1], fileCounts[2], fileCounts[3], fileCounts[4],
                    allSqlStatements.size());

        } catch (IOException e) {
            log.error("遍历目录失败: " + directoryPath, e);
        }

        return allSqlStatements;
    }

    @Override
    public List<SqlStatement> analyzeFile(Path filePath) {
        List<SqlStatement> sqlStatements = new ArrayList<>();

        try {
            if (!Files.exists(filePath) || !Files.isRegularFile(filePath)) {
                return sqlStatements;
            }

            String fileName = filePath.toString().toLowerCase();
            log.debug("分析文件: {}", filePath);

            // 根据文件类型选择合适的分析器
            if (fileName.endsWith(".xml")) {
                log.debug("检测到XML文件: {}", filePath);
                // 分析MyBatis XML文件
                if (mybatisXmlAnalysisService.isMybatisXmlFile(filePath)) {
                    log.debug("开始分析MyBatis XML文件: {}", filePath);
                    List<SqlStatement> xmlStatements = mybatisXmlAnalysisService.analyzeXmlFile(filePath);
                    sqlStatements.addAll(xmlStatements);
                    if (xmlStatements.size() > 0) {
                        log.info("XML文件分析完成: {} -> {} 条SQL语句", filePath, xmlStatements.size());
                    }
                } else {
                    log.debug("跳过非MyBatis XML文件: {}", filePath);
                }
            } else if (fileName.endsWith(".java")) {
                log.debug("检测到Java文件: {}", filePath);
                // 分析Java注解
                if (javaAnnotationAnalysisService.hasOrmAnnotations(filePath)) {
                    log.debug("开始分析Java注解文件: {}", filePath);
                    List<SqlStatement> javaStatements = javaAnnotationAnalysisService.analyzeJavaFile(filePath);
                    sqlStatements.addAll(javaStatements);
                    if (javaStatements.size() > 0) {
                        log.info("Java文件分析完成: {} -> {} 条SQL语句", filePath, javaStatements.size());
                    }
                } else {
                    log.debug("跳过无ORM注解的Java文件: {}", filePath);
                }
            } else if (fileName.endsWith(".sql")) {
                log.debug("检测到SQL文件: {}", filePath);
                log.info("SQL文件分析功能待实现: {}", filePath);
            }
            // 可以扩展支持其他文件类型，如.sql文件等

        } catch (Exception e) {
            log.error("分析文件失败: " + filePath, e);
        }

        return sqlStatements;
    }
}